#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2017/11/25 10:57
# @Author  : Beam
# @Site    : 
# @File    : authapi.py
# @Software: PyCharm

from django.views import View
import time
import hashlib
from django.http import JsonResponse


'''
reset api 认证
@所有要做api认证都先通过这个认证才可以继续做
'''

ENCRYPT_LIST = []   #存放认证过的key
from config import setting
from func.public_method import get_request_info
from func.writeLog import Loggers

def judge(request):
	message = get_request_info(request.META)
	# print(request.META)
	auth_key = request.META.get(setting.ASSET_AUTH_HEADER_NAME,None)
	if not auth_key:  #若没有获取设定的认证头，直接返回false
		message = message + " message:'Client没有提交指定的认证头！' "
		Loggers('api.log').log(message,False)
		return False
	sp = auth_key.split('|')
	if len(sp) != 2:   #认证格式不正确
		message = message + " message:'Client认证格式不正确！' "
		Loggers('api.log').log(message,False)
		return False
	encrypt,timestamp = sp
	timestamp = float(timestamp)  #转换float格式
	limit_timestamp = time.time() - setting.ASSET_AUTH_TIME
	# print(timestamp)
	# print(limit_timestamp)
	if limit_timestamp > timestamp:      #当前时间与客户端访问时时间戳对比，当超过5秒，属于超时
		message = message + " message:'Client认证超时！' "
		Loggers('api.log').log(message,False)
		return False
	ha = hashlib.md5(setting.ASSET_AUTH_KEY.encode("utf8"))
	ha.update(bytes("%s|%f" % (setting.ASSET_AUTH_KEY, timestamp), encoding='utf-8'))
	result = ha.hexdigest()
	if encrypt != result:   #md5验证
		message = message + " message:'Client的MD5验证失败！' "
		Loggers('api.log').log(message,False)
		return False
	exist = False
	del_key = []
	for k,v in enumerate(ENCRYPT_LIST):
		t = v['time']
		n = v['encrypt']
		if t < limit_timestamp:
			del_key.append(k)
			continue
		if n == encrypt:
			exist = True
		for k in del_key:
			del ENCRYPT_LIST[k]
		if exist:
			message = message + " message:'Client该key已失效！' "
			Loggers('api.log').log(message, False)
			return False
		ENCRYPT_LIST.append({'encrypt': encrypt, 'time': timestamp})
	message = message + " message:'认证成功！' "
	Loggers('api.log').log(message, True)
	return True

#调用该装饰器方法： @method_decorator(api_auth)
def api_auth(func):
	#装饰器：如果认证失败直接返回这个json
    def inner(request, *args, **kwargs):
        if not judge(request):
            return JsonResponse({'code': 1001, 'message': 'API授权失败'}, json_dumps_params={'ensure_ascii': False})
        return func(request, *args, **kwargs)
    return inner